package edu.ynu.hhy.architectureclass.service;

import edu.ynu.hhy.architectureclass.dao.SensorDataDao;
import edu.ynu.hhy.architectureclass.entity.SensorData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.*;

@Service
public class SensorDataService {

    @Autowired
    private SensorDataDao sensorDataDao;

    @Autowired
    private RestTemplate restTemplate;

    @Value("${fbox.api.sensor.url}")
    private String fboxSensorUrl;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private DeviceService deviceService;

    public List<SensorData> getSensorData() {
        String boxNo = "300023040071"; // 固定的 boxNo

        // 获取设备表中所有 category 为 "sensor" 的 serialNumber
        List<String> deviceSerials = deviceService.getAllSensorDeviceSerials();

        // 获取 accessToken
        String accessToken = tokenService.getFBoxToken();
        if (accessToken == null) {
            System.err.println("Failed to get access token");
            return null;
        }

        // 构造请求体
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("ids", deviceSerials);

        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "Bearer " + accessToken);
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);

        try {
            ResponseEntity<List> response = restTemplate.exchange(
                    fboxSensorUrl + "?boxNo=" + boxNo,
                    HttpMethod.POST,
                    request,
                    List.class
            );

            if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
                List<Map<String, Object>> responseBody = (List<Map<String, Object>>) response.getBody();
                // 解析响应数据并转换为 SensorData 对象
                List<SensorData> sensorDataList = parseSensorDataResponse(responseBody);
                return sensorDataList;
            } else {
                System.err.println("API 调用失败，状态码: " + response.getStatusCode());
                System.err.println("响应内容: " + response.getBody());
            }
        } catch (Exception e) {
            System.err.println("API 调用异常: " + e.getMessage());
            e.printStackTrace();
        }

        return null;
    }

    private List<SensorData> parseSensorDataResponse(List<Map<String, Object>> responseBody) {
        List<SensorData> sensorDataList = new ArrayList<>();
        for (Map<String, Object> data : responseBody) {
            SensorData sensorData = new SensorData();
            sensorData.setDeviceSerial((String) data.get("id")); // 设备序列号
            sensorData.setName((String) data.get("name")); // 传感器名称

            // 处理 value 字段，支持 Integer 和 Double 类型
            Object value = data.get("value");
            double finalValue = 0.0;

            if (value instanceof Integer) {
                finalValue = ((Integer) value).doubleValue(); // 将 Integer 转换为 Double
            } else if (value instanceof Double) {
                finalValue = (Double) value; // 直接使用 Double
            } else {
                // 如果 value 是其他类型，可以记录日志或抛出异常
                System.err.println("Unexpected value type: " + value.getClass().getName());
            }

            // 对空气温度和空气相对湿度传感器的数据进行特殊处理
            String sensorName = sensorData.getName();
            if ("空气温度传感器".equals(sensorName) || "空气相对湿度传感器".equals(sensorName)) {
                finalValue = finalValue / 10.0; // 除以 10 得到实际值
            }

            sensorData.setValue(finalValue); // 设置最终值
            sensorDataList.add(sensorData);
        }
        return sensorDataList;
    }

    public SensorData saveSensorData(SensorData sensorData) {
        sensorData.setCreateTime(new Date());
        return sensorDataDao.save(sensorData);
    }
}